//
//  NSDictionary+Parameters.m
//  QTCategory
//
//  Created by 张俊博 on 2016/10/17.
//  Copyright © 2016年 CISDI. All rights reserved.
//

#import "NSDictionary+Parameters.h"
#import "NSString+QTAdd.h"

@interface NSString (QueryToObject)
- (BOOL)IsURLQueryIndex;
@end

@implementation NSString (QueryToObject)
- (BOOL)IsURLQueryIndex
{
    unichar firstLetter = [self characterAtIndex:0];
    return (firstLetter>='0') && (firstLetter<='9');
}
@end

@interface NSMutableArray (ParametersKVC)
- (void)setObject:(id)object forURLQueryKey:(NSString*)key;
- (id)objectForURLQueryKey:(NSString*)key;
@end

@implementation NSMutableArray (ParametersKVC)
- (void)setObject:(id)object forURLQueryKey:(NSString*)key
{
    NSUInteger index = [key integerValue];
    NSUInteger fillUpIndex = [self count];
    
    while (fillUpIndex++<=index)
    {
        [self addObject:[NSNull null]];
    }
    self[index] = object;
}

- (id)objectForURLQueryKey:(NSString*)key
{
    NSUInteger index = [key integerValue];
    id object = [NSNull null];
    if ([self count]<=index)
    {
        [self setObject:object forURLQueryKey:key];
    }
    else
    {
        object = self[index];
    }
    return object;
}
@end

@interface NSMutableDictionary (ParametersKVC)
- (void)setObject:(id)object forURLQueryKey:(NSString*)key;
- (id)objectForURLQueryKey:(NSString*)key;
@end

@implementation NSMutableDictionary (ParametersKVC)
- (void)setObject:(id)object forURLQueryKey:(NSString*)key
{
    self[key]=object;
}

- (id)objectForURLQueryKey:(NSString*)key
{
    id object = self[key];
    if (object==nil)
    {
        object = [NSNull null];
        self[key]=object;
    }
    return object;
}
@end

@implementation NSMutableDictionary (Parameters)

- (void)setObject:(NSString*)value forURLQueryKeyPath:(NSString*)keyPath keyPrefix:(NSString*)keyPrefix keyPostfix:(NSString*)keyPostfix
{
    value = [value  stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    keyPath = [keyPath stringByReplacingOccurrencesOfString:keyPostfix withString:@""];
    NSArray *keys = [keyPath componentsSeparatedByString:keyPrefix];
    
    NSAssert([keys count]>0, @"no components at all!?!?!?!");
    
    NSUInteger keyIndex = 0;
    id omi = nil;
    id parent = nil;
    id node = self;
    
    NSString *key;
    NSString *parentKey;
    while (keyIndex<([keys count]-1))
    {
        parentKey = key;
        key = keys[keyIndex++];
        key = [key stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
        omi = parent;
        parent = node;
        
        Class collectionClass;
        if ([key IsURLQueryIndex])
        {
            collectionClass = [NSMutableArray class];
        }
        else
        {
            collectionClass = [NSMutableDictionary class];
        }
        
        if ([parent isKindOfClass:[NSNull class]])
        {
            parent = [collectionClass new];
            [omi setObject:parent forURLQueryKey:parentKey];
        }
        
        else if (![parent isKindOfClass:collectionClass])
        {
            return;
        }
        node = [parent objectForURLQueryKey:key];
    }
    parentKey = key;
    key = keys[keyIndex];
    if ([key IsURLQueryIndex])
    {
        if ([node isKindOfClass:[NSNull class]]) {
            node =[NSMutableArray new];
            [parent setObject:node forURLQueryKey:parentKey];
        }
    }
    else
    {
        if ([node isKindOfClass:[NSNull class]])
        {
            node = [NSMutableDictionary new];
            [parent setObject:node forURLQueryKey:parentKey];
        }
    }
    [node setObject:value forURLQueryKey:key];
}

- (void)setObject:(NSString*)value forURLQueryKeyPath:(NSString*)keyPath
{
    [self setObject:value forURLQueryKeyPath:keyPath keyPrefix:[[self class] defaultURLQueryKeyPrefix] keyPostfix:[[self class] defaultURLQueryKeyPostfix]];
}
@end

@implementation NSDictionary (Parameters)

static NSString *_keyPrefix = @"[";

+ (void)setDefaultURLQueryKeyPrefix:(NSString*)delimiter
{
    _keyPrefix = delimiter;
}

+ (NSString*)defaultURLQueryKeyPrefix
{
    return _keyPrefix;
}

static NSString *_keyPostfix = @"]";

+ (void)setDefaultURLQueryKeyPostfix:(NSString*)delimiter
{
    _keyPostfix = delimiter;
}

+ (NSString*)defaultURLQueryKeyPostfix
{
    return _keyPostfix;
}

static NSString *_delimiter = @"&";

+ (NSString*)defaultURLQueryPairsDelimiter
{
    return _delimiter;
}

+ (void)setDefaultURLQueryPairsDelimiter:(NSString*)delimiter
{
    _delimiter = delimiter;
}

+ (NSDictionary*)objectsFromURLQueryString:(NSString*)query
{
    return [self objectsFromURLQueryString:query withPairsDelimiter:[self defaultURLQueryPairsDelimiter] keyPrefix:[self defaultURLQueryKeyPrefix] keyPostFix:[self defaultURLQueryKeyPostfix]];
}

+ (NSDictionary*)objectsFromURLQueryString:(NSString*)query withPairsDelimiter:(NSString*)delimiter keyPrefix:(NSString*)keyPrefix keyPostFix:(NSString*)keyPostfix
{
    NSArray *assignments = [query componentsSeparatedByString:delimiter];
    
    NSMutableDictionary *keyValuePairs = [NSMutableDictionary new];
    for (NSString *assignment in assignments)
    {
        NSUInteger equalsSignLocation = [assignment rangeOfString:@"="].location;
        if (equalsSignLocation==NSNotFound)
        {
            return nil;
        }
        
        NSString *keyPath = [assignment substringToIndex:equalsSignLocation];
        NSString *value = [assignment substringFromIndex:equalsSignLocation+1];
        value = [value stringByRemovingPercentEncoding];
        if (value==nil) {
            value = @"";
        }
        
        
        [keyValuePairs setObject:value forURLQueryKeyPath:keyPath keyPrefix:keyPrefix keyPostfix:keyPostfix];
        
    }
    return keyValuePairs;
}

+ (NSDictionary *)parametersFromString:(NSString *)string
{
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    NSArray* paramStringArr = [string componentsSeparatedByString:@"&"];
    for (NSString* paramString in paramStringArr) {
        NSArray* paramArr = [paramString componentsSeparatedByString:@"="];
        if (paramArr.count > 1) {
            NSString* key = [[paramArr objectAtIndex:0] stringByRemovingPercentEncoding].stringByURLDecode;
            NSString* value = [[paramArr objectAtIndex:1] stringByRemovingPercentEncoding].stringByURLDecode;
            
            key = [key stringByReplacingOccurrencesOfString:[self defaultURLQueryKeyPrefix] withString:@""];
            key = [key stringByReplacingOccurrencesOfString:[self defaultURLQueryKeyPostfix] withString:@""];
            
            id parameter = parameters[key];
            if (!parameter) {
                parameters[key] = value;
            } else {
                if ([parameter isKindOfClass:[NSMutableArray class]]) {
                    [parameter addObject:value];
                } else {
                    NSMutableArray *array = [NSMutableArray arrayWithObject:parameter];
                    [array addObject:value];
                    parameters[key] = array;
                }
            }
        }
    }
    return parameters;
}

- (NSString *)parametersString
{
    if (!self || self.count<=0) {
        return nil;
    }
    NSMutableArray* pairs = [NSMutableArray array];
    for (NSString* key in self.keyEnumerator) {
        id value = [self objectForKey:key];
        if ([value isKindOfClass:[NSArray class]]) {
            for (id _value in value) {
                NSString* value = [NSString stringWithFormat:@"%@", _value];
                [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, value.stringByRouterURLEncode]];
            }
        } else if ([value isKindOfClass:[NSDictionary class]]) {
            [pairs addObject:[value parametersString]];
        } else {
            NSString* value = [NSString stringWithFormat:@"%@", [self objectForKey:key]];
            [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, value.stringByRouterURLEncode]];
        }
    }
    return  [pairs componentsJoinedByString:@"&"];
}

@end
